home *** CD-ROM | disk | FTP | other *** search
- /******************************************************************************
-
- MODUL
- redraw.c
-
- DESCRIPTION
- This contains all functionality that is needed to refresh
- part of the display.
-
- ******************************************************************************/
-
- /**************************************
- Includes
- **************************************/
- #include <defs.h>
- #define MYDEBUG 0
- #include "debug.h"
-
-
- /**************************************
- Globale Variable
- **************************************/
- Prototype void redraw_block (BOOL, Line, Column, Line, Column);
-
-
- /**************************************
- Interne Defines & Strukturen
- **************************************/
- #define SWAP(a,b) (void)((a)^=(b),(b)^=(a),(a)^=(b))
- #define MIN(a,b) ((a) <= (b) ? (a) : (b))
- #define MAX(a,b) ((a) >= (b) ? (a) : (b))
- #define CLIP(l,m,h) (((m) < (l)) ? (l) : (((m) > (h)) ? (h) : (m)))
-
- #define BF_LINESWAP 1L
- #define BF_COLUMNSWAP 2L
-
-
- /**************************************
- Interne Variable
- **************************************/
-
-
- /**************************************
- Interne Prototypes
- **************************************/
-
-
- /*****************************************************************************
-
- NAME
- redraw_block
-
- PARAMETER
- BOOL force; Shall I care for the difference between
- the fields in the ActualBlock or just
- redraw the block in the limits specified
- in the parameters ?
- Line start_line;
- Column start_column;
- Line end_line;
- Column end_column;
-
- RETURN
- void
-
- DESCRIPTION
- This function draws a block according to the type. The parameter
- force has a special meaning. If it is TRUE, you force a redraw.
- The block is newly drawn. In this case, the lines specify the
- clip-rect of text that is to be redrawn.
- If it is FALSE, the positions specify the new start- and
- end-positions for the block. The routine gurantees that the
- start-position of the block is before the end-position after the
- call. It is valid to call the routine with -1/-1 for one position.
- In this case, you just want to move one position without touching
- the other. The routine also takes care for flipping the block.
-
- NOTES
- - If force is FALSE, you MUST NOT change more than one position at
- a time. You can exchange both and change one, though.
- - The block is only redrawn, if the actual editor is the editor
- with the block and drawing in that editor is ok !
- - After the call, the new positions are written into the ActualBlock-
- struct if force is FALSE. It is guranteed, that the start-position
- is before the end-position, no matter how they were when the routine
- was called.
-
- ******************************************************************************/
-
- /* We note all areas that need to be drawn/erased in this structure.
-
- (startline<=endline && startcol<=endcol) == TRUE !
- */
-
- #define NO_INTERSECT 0
- #define TOP_CLIP 0x0001
- #define BOTTOM_CLIP 0x0010
- #define LEFT_CLIP 0x0100
- #define RIGHT_CLIP 0x1000
- #define TOP_INTERSECT 0x0002
- #define BOTTOM_INTERSECT 0x0020
- #define LEFT_INTERSECT 0x0200
- #define RIGHT_INTERSECT 0x2000
-
- #define IS_EMPTY 0
- #define NOT_EMPTY 1
- #define MEMORY_ERROR 2
-
- struct RefreshRegion
- {
- MLIST list; /* linked list of regions */
- };
-
- struct rect
- {
- Line sl; /* line where the region starts in */
- Column sc; /* and the column */
- Line el; /* same for end-pos */
- Column ec;
- };
-
-
- struct MyRegion
- {
- MNODE node; /* for linking into a list */
- struct rect rect;
- };
-
-
- struct RefreshRegion * new_region (void);
- void dispose_region (struct RefreshRegion *);
- UWORD do_clip (struct MyRegion *, struct rect *);
- int and_rect_region (struct RefreshRegion *, struct rect *);
- BOOL add_rect (struct RefreshRegion *, struct rect *);
- int clear_rect_region (struct RefreshRegion *, struct rect *);
- void refresh_region (RP *, struct RefreshRegion *, int);
- void print_region (struct RefreshRegion *);
-
-
- void print_region (struct RefreshRegion * region)
- {
- struct MyRegion * ptr;
- int t;
-
- for (t=0,ptr=GetHead(®ion->list); ptr; ptr=GetSucc(&ptr->node),t++)
- {
- D(bug("Node %ld: (%ld/%ld) - (%ld/%ld)\n",
- t, ptr->rect.sl, ptr->rect.sc, ptr->rect.el, ptr->rect.ec));
- }
- } /* print_region */
-
-
- struct RefreshRegion * new_region (void)
- {
- struct RefreshRegion * new;
-
- if (new = AllocMem (sizeof(struct RefreshRegion), 0))
- {
- NewList ((struct List *)&new->list);
- }
-
- return (new);
- } /* new_region */
-
-
- void dispose_region (struct RefreshRegion * region)
- {
- struct MyRegion * ptr, * next;
-
- for (ptr=GetHead(®ion->list); ptr; ptr=next)
- {
- next = GetSucc (&ptr->node);
-
- FreeMem (ptr, sizeof(struct MyRegion));
- }
-
- FreeMem (region, sizeof(struct RefreshRegion));
- } /* dispose_region */
-
-
- UWORD do_clip (struct MyRegion * region, struct rect * rect)
- {
- UWORD test = NO_INTERSECT;
-
- if (!( (region->rect.sl > rect->el) || (region->rect.el < rect->sl) ||
- (region->rect.sc > rect->ec) || (region->rect.ec < rect->sc) ) )
- {
- if (region->rect.sl < rect->sl)
- test |= TOP_CLIP;
-
- if (region->rect.el > rect->el)
- test |= BOTTOM_CLIP;
-
- if (region->rect.sc < rect->sc)
- test |= LEFT_CLIP;
-
- if (region->rect.ec > rect->ec)
- test |= RIGHT_CLIP;
-
- if (region->rect.sl <= rect->el)
- test |= TOP_INTERSECT;
-
- if (region->rect.el >= rect->sl)
- test |= BOTTOM_INTERSECT;
-
- if (region->rect.sc <= rect->ec)
- test |= LEFT_INTERSECT;
-
- if (region->rect.ec >= rect->sc)
- test |= RIGHT_INTERSECT;
- }
-
- /* D(bug("clip %04lx\n", test)); */
-
- return (test);
- } /* do_clip */
-
-
- /* clip regions */
-
- int and_rect_region (struct RefreshRegion * region, struct rect * rect)
- {
- struct MyRegion * ptr, * next;
- UWORD status;
-
- for (ptr=GetHead(®ion->list); ptr; ptr=next)
- {
- UWORD common;
-
- next = GetSucc (&ptr->node);
-
- if ((common = do_clip (ptr, rect)) != NO_INTERSECT)
- {
- if (common & TOP_CLIP)
- ptr->rect.sl = rect->sl;
-
- if (common & BOTTOM_CLIP)
- ptr->rect.el = rect->el;
-
- if (common & LEFT_CLIP)
- ptr->rect.sc = rect->sc;
-
- if (common & RIGHT_CLIP)
- ptr->rect.ec = rect->ec;
- }
- else
- {
- /* if they do not intersect, remove the Region */
-
- Remove ((struct Node *)&ptr->node);
-
- FreeMem (ptr, sizeof(struct MyRegion));
- }
- }
-
- if (!GetHead(region))
- status = IS_EMPTY;
- else
- status = NOT_EMPTY;
-
- return (status);
- } /* and_rect_region */
-
-
- /* make a copy of a region */
-
- struct RefreshRegion * copy_region (struct RefreshRegion * region)
- {
- struct MyRegion * ptr;
- struct RefreshRegion * copy;
-
- if (copy = new_region ())
- {
- for (ptr=GetHead(®ion->list); ptr; ptr=GetSucc(&ptr->node))
- {
- if (!(add_rect (copy, &ptr->rect)) )
- {
- dispose_region (copy);
-
- return (NULL);
- }
- }
- }
-
- return (copy);
- } /* copy_region */
-
-
- /* make erase all common areas between two regions */
-
- void clip_region (struct RefreshRegion * region, struct RefreshRegion * clip)
- {
- struct MyRegion * ptr;
-
- for (ptr=GetHead(&clip->list); ptr; ptr=GetSucc(&ptr->node))
- {
- clear_rect_region (region, &ptr->rect);
- }
- } /* clip_region */
-
-
- /* create a new Region and add it to the RefreshRegion. This routine
- must not be called with a rect that intersects with any of the
- Regions that are already in the RefreshRegion ! */
-
- BOOL add_rect (struct RefreshRegion * region, struct rect * rect)
- {
- struct MyRegion * new;
-
- if (new = AllocMem (sizeof(struct MyRegion), 0))
- {
- movmem (rect, &new->rect, sizeof (struct rect));
-
- /* AddHead because we might be editing the list right now :-) */
- AddHead ((struct List *)®ion->list, (struct Node *)&new->node);
- }
-
- return ((BOOL)(new != NULL));
- } /* add_rect */
-
-
- /* adjust regions that none intersects with the rect anymore */
-
- int clear_rect_region (struct RefreshRegion * region, struct rect * rect)
- {
- struct MyRegion * ptr, * next;
- UWORD status;
-
- for (ptr=GetHead(®ion->list); ptr; ptr=next)
- {
- UWORD common;
- struct rect new_rect;
-
- next = GetSucc (&ptr->node);
-
- /* do something only if we have an intersection */
-
- if ((common = do_clip (ptr, rect)) != NO_INTERSECT)
- {
- /* if both intersect, we make sure we don't have any areas left
- that are in two Regions */
-
- if (common & TOP_CLIP)
- {
- /* if we have a TOP_CLIP, there must be some new Region
- above. */
-
- new_rect.sl = ptr->rect.sl;
- new_rect.el = rect->sl - 1; /* this is the intersection */
- new_rect.sc = ptr->rect.sc;
- new_rect.ec = ptr->rect.ec;
-
- /* is this a valid rect anyway ?? */
- if (new_rect.sl <= new_rect.el)
- {
- if (!add_rect (region, &new_rect))
- return (MEMORY_ERROR);
- else
- ptr->rect.sl = rect->sl; /* new topline */
- } /* valid rect ? */
- } /* type of intersect */
-
- if (common & BOTTOM_CLIP)
- {
- /* if we have a BOTTOM_CLIP, there must be some new Region
- below. */
-
- new_rect.sl = rect->el + 1; /* clipping */
- new_rect.el = ptr->rect.el;
- new_rect.sc = ptr->rect.sc;
- new_rect.ec = ptr->rect.ec;
-
- /* is this a valid rect anyway ?? */
- if (new_rect.sl <= new_rect.el)
- {
- if (!add_rect (region, &new_rect))
- return (MEMORY_ERROR);
- else
- ptr->rect.el = rect->el;
- } /* valid rect ? */
- } /* type of intersect */
-
- if (common & LEFT_CLIP)
- {
- /* if we have a LEFT_CLIP, there must be some new Region
- below. */
-
- new_rect.sl = ptr->rect.sl;
- new_rect.el = ptr->rect.el;
- new_rect.sc = ptr->rect.sc;
- new_rect.ec = rect->sc - 1; /* clipping */
-
- /* is this a valid rect anyway ?? */
- if (new_rect.sc <= new_rect.ec)
- {
- if (!add_rect (region, &new_rect))
- return (MEMORY_ERROR);
-
- /* we do not need any ELSE here since RIGHT_CLIP
- doesn't care about the left border. */
-
- } /* valid rect ? */
- } /* type of intersect */
-
- if (common & RIGHT_CLIP)
- {
- /* if we have a RIGHT_CLIP, there must be some new Region
- below. */
-
- new_rect.sl = ptr->rect.sl;
- new_rect.el = ptr->rect.el;
- new_rect.sc = rect->ec + 1; /* clipping */
- new_rect.ec = ptr->rect.ec;
-
- /* is this a valid rect anyway ?? */
- if (new_rect.sc <= new_rect.ec)
- {
- if (!add_rect (region, &new_rect))
- return (MEMORY_ERROR);
- } /* valid rect ? */
- } /* type of intersect */
-
- /* remove old area */
- Remove ((struct Node *)&ptr->node);
-
- FreeMem (ptr, sizeof (struct MyRegion));
- } /* intersection */
- }
-
- if (!GetHead(region))
- status = IS_EMPTY;
- else
- status = NOT_EMPTY;
-
- return (status);
- } /* clear_rect_region */
-
-
- int AddDrawEvent (struct RefreshRegion * region, Line sl, Column sc,
- Line el, Column ec)
- {
- struct rect new_rect;
-
- if (el < sl || ec < sc) /* don't add invalid blocks */
- return (TRUE);
-
- new_rect.sl = sl;
- new_rect.el = el;
- new_rect.sc = sc;
- new_rect.ec = ec;
-
- return (add_rect (region, &new_rect));
- } /* AddDrawEvent */
-
-
- /*****************************************************************************
-
- NAME
- redraw_block
-
- PARAMETER
- BOOL force;
- Line start_line;
- Column start_column;
- Line end_line;
- Column end_column;
-
- RESULT
-
- RETURN
- void
-
- DESCRIPTION
- Draws part of the text (force = TRUE) or adjust the block
- accurding to the new coordinates (force = FALSE).
-
- NOTES
-
- BUGS
-
- EXAMPLES
-
- SEE ALSO
-
- INTERNALS
-
- HISTORY
- 03. Jan 1978 ada created
-
- ******************************************************************************/
-
- void redraw_block (BOOL force, Line start_line, Column start_column,
- Line end_line, Column end_column)
- {
- RP * rp;
- struct RefreshRegion * old, /* the old block that has to be erased */
- * new, /* the new block that has to be drawn */
- * update, /* region where we have to redraw the
- text */
- * copy; /* and a copy of old for removing common
- areas. */
- struct rect new_rect;
-
- D(bug("----> redraw_block\nforce:%ld start:%3ld/%3ld end:%3ld/%3ld\n",
- force,
- start_line+1, start_column+1,
- end_line+1, end_column+1 ));
-
- old = new_region ();
- new = new_region ();
- update = new_region ();
-
- if (!old || !new || !update) /* out of memory */
- return;
-
- if (block_ok () && ActualBlock.ep == Ep) /* do this only if there really is a block */
- {
- if (ActualBlock.start_line > ActualBlock.end_line)
- {
- SWAP (ActualBlock.start_line, ActualBlock.end_line);
-
- ActualBlock.flags ^= BF_LINESWAP;
-
- if ( ActualBlock.type == BT_NORMAL ||
- ActualBlock.start_column > ActualBlock.end_column)
- {
- SWAP (ActualBlock.start_column, ActualBlock.end_column);
-
- ActualBlock.flags ^= BF_COLUMNSWAP;
- }
- } else if ((ActualBlock.type == BT_VERTICAL ||
- (ActualBlock.start_line == ActualBlock.end_line &&
- ActualBlock.type == BT_NORMAL)) &&
- ActualBlock.start_column > ActualBlock.end_column)
- {
- SWAP (ActualBlock.start_column, ActualBlock.end_column);
-
- ActualBlock.flags ^= BF_COLUMNSWAP;
- }
- }
- else /* no matter what we have to do: it cannot be something that
- has to do with a block. So we just redraw the current area. */
- {
- update_only: /* jump here if we are sure there is no block to draw */
-
- D(bug("Update only\n"));
-
- if (end_line < start_line)
- SWAP(start_line,end_line);
-
- if (end_column < start_column)
- SWAP(start_column,end_column);
-
- AddDrawEvent (update, start_line, start_column,
- end_line, end_column);
-
- goto draw; /* I really don't like goto but I also don't
- want to indent all those mush below :-) */
- }
-
- /* find drawing positions. After this if, the redraw-struct is filled with
- all information to draw the new situation */
- if (force)
- {
- /* here, we must make sure, that start <= end ! */
- if (start_line > end_line)
- {
- SWAP (start_line, end_line);
-
- if (ActualBlock.type == BT_NORMAL)
- SWAP (start_column, end_column);
- else if (ActualBlock.type == BT_VERTICAL &&
- start_column > end_column)
- SWAP (start_column, end_column);
- } else if (((start_line == end_line && ActualBlock.type == BT_NORMAL) ||
- ActualBlock.type == BT_VERTICAL) &&
- start_column > end_column)
- SWAP (start_column, end_column);
-
- /* clip end-line */
- if (end_line >= Ep->lines)
- end_line = Ep->lines-1;
-
- if (globalflags.Comlinemode)
- {
- text_redraw_cmdline ();
- return;
- } else {
- /* clip all areas against the draw-area */
- new_rect.sl = start_line;
- new_rect.el = end_line;
- new_rect.sc = start_column;
- new_rect.ec = end_column;
-
- switch (ActualBlock.type)
- {
- case BT_LINE:
- {
- AddDrawEvent (update, start_line, start_column,
- ActualBlock.start_line - 1, end_column);
- AddDrawEvent (new,
- ActualBlock.start_line, start_column,
- ActualBlock.end_line, end_column);
- AddDrawEvent (update, ActualBlock.end_line + 1, start_column,
- end_line, end_column);
- }
- break;
-
- case BT_VERTICAL:
- {
- /* this is something like this:
-
- +---------------------+
- | (A) |
- +-----+-------+-------+
- | (B) | (C) | (D) |
- +-----+-------+-------+
- | (E) |
- +---------------------+
- */
-
- AddDrawEvent (update, start_line, start_column,
- ActualBlock.start_line - 1, end_column);
- AddDrawEvent (update,
- ActualBlock.start_line, start_column,
- ActualBlock.end_line, ActualBlock.start_column - 1);
- AddDrawEvent (new,
- ActualBlock.start_line, ActualBlock.start_column,
- ActualBlock.end_line, ActualBlock.end_column);
- AddDrawEvent (update,
- ActualBlock.start_line, ActualBlock.end_column + 1,
- ActualBlock.end_line, end_column);
- AddDrawEvent (update, ActualBlock.end_line + 1, start_column,
- end_line, end_column);
-
- }
- break;
-
- case BT_NORMAL:
- {
- Column scol, ecol;
- int start_len, end_len;
-
- /* The situation is like this :
-
- +-----------------------+
- | (A) | (A) The area above the block
- | +------------+ (B) The area in the line where
- | (B) | (C) | the block starts BEFORE the
- +----------+------------+ block
- | (D) | (C) The area inside the block in
- +-------------+---------+ the line where the block
- | (E) | (F) | begins
- +-------------+ | (D) the main body
- | (G) | (E) the rest of the block in the
- +-----------------------+ last line
- (F) the rest of this line
- (G) anything below the block
-
- */
-
- start_len = LINELEN(Ep,ActualBlock.start_line);
-
- if (start_len <= ActualBlock.start_column)
- scol = start_len;
- else
- scol = ActualBlock.start_column;
-
- AddDrawEvent (update, start_line, start_column,
- ActualBlock.start_line-1, end_column);
-
- end_len = LINELEN(Ep,ActualBlock.end_line);
-
- if (end_len <= ActualBlock.end_column)
- ecol = end_column;
- else
- ecol = ActualBlock.end_column;
-
- if (ActualBlock.start_line != ActualBlock.end_line)
- {
- /* (B) (C) */
- AddDrawEvent (update,
- ActualBlock.start_line, start_column,
- ActualBlock.start_line, scol-1);
- AddDrawEvent (new,
- ActualBlock.start_line, scol,
- ActualBlock.start_line, end_column);
-
- /* (D) */
- AddDrawEvent (new,
- ActualBlock.start_line+1, start_column,
- ActualBlock.end_line-1, end_column);
-
- /* (E) (F) */
- AddDrawEvent (new,
- ActualBlock.end_line, start_column,
- ActualBlock.end_line, ecol);
- AddDrawEvent (update,
- ActualBlock.end_line, ecol+1,
- ActualBlock.end_line, end_column);
- } else
- {
- AddDrawEvent (update,
- ActualBlock.start_line, start_column,
- ActualBlock.start_line, scol-1);
-
- AddDrawEvent (new,
- ActualBlock.start_line, scol,
- ActualBlock.start_line, ecol);
-
- AddDrawEvent (update,
- ActualBlock.start_line, ecol+1,
- ActualBlock.start_line, end_column);
- }
-
- /* (G) */
- AddDrawEvent (update, ActualBlock.end_line+1, start_column,
- end_line, end_column);
-
- /* if (start_len <= ActualBlock.start_column)
- start_column = start_len;
-
- if (end_len <= ActualBlock.end_column)
- end_column = end_len; dead assign */
- }
- break;
- } /* switch */
-
- and_rect_region (update, &new_rect);
- and_rect_region (new, &new_rect);
-
- /* D(bug("Update :\n")); print_region (update);
- D(bug("new :\n")); print_region (new); */
- }
- } else /* force == FALSE */
- {
- Line top, bottom;
- Column left, right;
-
- D(bug("Flags %ld\n", ActualBlock.flags));
-
- top = ActualBlock.start_line;
- bottom = ActualBlock.end_line;
- left = ActualBlock.start_column;
- right = ActualBlock.end_column;
-
- if (ActualBlock.flags & BF_LINESWAP)
- SWAP (top, bottom);
-
- if (ActualBlock.flags & BF_COLUMNSWAP)
- SWAP (left, right);
-
- if (start_line == -1) /* find correct start-pos */
- {
- start_line = top;
- start_column = left;
- } else if (end_line == -1) /* find correct end-pos */
- {
- end_line = bottom;
- end_column = right;
- }
-
- D(bug("Drawing: start:%3ld/%3ld end:%3ld/%3ld\n",
- start_line+1,
- start_column+1,
- end_line+1,
- end_column+1
- ));
- D(bug("(old) start:%3ld/%3ld end:%3ld/%3ld\n",
- ActualBlock.start_line+1,
- ActualBlock.start_column+1,
- ActualBlock.end_line+1,
- ActualBlock.end_column+1
- ));
-
- left = Ep->topcolumn;
- /* top = Ep->topline; dead assign */
- right = left + Columns - 1;
- /* bottom = top + Lines - 1; dead assign */
-
- /* all these routines work basically the same way. First,
- we copy the start- and end-pos. Then we make sure that
- the start-pos is before to end-pos. Now we check if the new
- block is visible.
-
- We have 2 versions of every positions, one normal and one
- clipped against the window-borders.
- The sl/el/sc/ec-coords are the sorted new positions, csl/cel/...
- are the clipped version, the old positions are in ActualBlock.xx
- and the clipped version in osl/sel/...
- */
-
- switch (ActualBlock.type)
- {
- case BT_LINE:
- {
- Line sl, el;
-
- sl = start_line;
- el = end_line;
-
- if (el < sl)
- SWAP(sl,el);
-
- AddDrawEvent (old, ActualBlock.start_line, left,
- ActualBlock.end_line, right);
- AddDrawEvent (new, sl, left, el, right);
- }
- break;
-
- case BT_NORMAL:
- {
- Line sl, el;
- Column sc, ec, scol, ecol;
- int slen, elen;
- UWORD flags;
-
- sl = start_line;
- el = end_line;
- sc = start_column;
- ec = end_column;
-
- flags = 0;
-
- if (el < sl)
- {
- SWAP (sl, el);
- SWAP (sc, ec);
-
- flags |= BF_LINESWAP | BF_COLUMNSWAP;
- } else if (sl == el && ec < sc)
- {
- SWAP (sc, ec);
-
- flags |= BF_COLUMNSWAP;
- }
-
- slen = LINELEN(Ep,ActualBlock.start_line);
-
- if (slen <= ActualBlock.start_column)
- scol = slen;
- else
- scol = ActualBlock.start_column;
-
- elen = LINELEN(Ep,ActualBlock.end_line);
-
- if (elen <= ActualBlock.end_column)
- ecol = right;
- else
- ecol = ActualBlock.end_column;
-
- if (ActualBlock.start_line != ActualBlock.end_line)
- {
- AddDrawEvent (old,
- ActualBlock.start_line, scol,
- ActualBlock.start_line, right);
-
- AddDrawEvent (old,
- ActualBlock.start_line+1, left,
- ActualBlock.end_line-1, right);
-
- AddDrawEvent (old,
- ActualBlock.end_line, left,
- ActualBlock.end_line, ecol);
- }
- else
- AddDrawEvent (old,
- ActualBlock.start_line, scol,
- ActualBlock.start_line, ecol);
-
- slen = LINELEN(Ep,sl);
-
- if (slen <= sc)
- scol = slen;
- else
- scol = sc;
-
- elen = LINELEN(Ep,el);
-
- if (elen <= ec)
- ecol = right;
- else
- ecol = ec;
-
- if (sl != el)
- {
- AddDrawEvent (new, sl, scol, sl, right);
- AddDrawEvent (new, sl+1, left, el-1, right);
- AddDrawEvent (new, el, left, el, ecol);
- }
- else
- AddDrawEvent (new, sl, scol, sl, ecol);
-
- if (slen <= sc)
- sc = slen;
-
- if (elen <= ec)
- ec = elen;
-
- if (flags & BF_COLUMNSWAP)
- SWAP(sc,ec);
-
- start_column = sc;
- end_column = ec;
- }
- break;
-
- case BT_VERTICAL:
- {
- Line sl, el;
- Column sc, ec;
-
- /* create sorted coords for new block */
- sl = start_line;
- el = end_line;
- sc = start_column;
- ec = end_column;
-
- if (el < sl) SWAP(sl,el);
- if (ec < sc) SWAP(sc,ec);
-
- AddDrawEvent (old,
- ActualBlock.start_line, ActualBlock.start_column,
- ActualBlock.end_line, ActualBlock.end_column);
- AddDrawEvent (new, sl, sc, el, ec);
-
- /* that's all folx ! */
- }
- break;
- } /* switch (ActualBlock.type) */
-
- copy = copy_region (old); /* make a copy of the old block */
-
- clip_region (old, new); /* clear all common areas in old */
- clip_region (new, copy); /* clear all common areas in new */
-
- dispose_region (copy); /* free copy */
-
- /* undo swap drawing-positions accordingly to blockflags */
- /* if (ActualBlock.flags & BF_LINESWAP)
- SWAP (start_line, end_line);
-
- if (ActualBlock.flags & BF_COLUMNSWAP)
- SWAP (start_column, end_column); */
-
- D(bug("copy: start:%3ld/%3ld end:%3ld/%3ld\n",
- start_line+1,
- start_column+1,
- end_line+1,
- end_column+1
- ));
-
- /* copy new positions */
- ActualBlock.start_line = start_line;
- ActualBlock.start_column = start_column;
- ActualBlock.end_line = end_line;
- ActualBlock.end_column = end_column;
-
- ActualBlock.flags &= ~(BF_LINESWAP | BF_COLUMNSWAP);
-
- /* reset flags */
- if (ActualBlock.start_line > ActualBlock.end_line)
- {
- SWAP (ActualBlock.start_line, ActualBlock.end_line);
-
- ActualBlock.flags |= BF_LINESWAP;
-
- if (ActualBlock.type == BT_NORMAL)
- {
- SWAP (ActualBlock.start_column, ActualBlock.end_column);
-
- ActualBlock.flags |= BF_COLUMNSWAP;
- } else if (ActualBlock.type == BT_VERTICAL)
- {
- if (ActualBlock.start_column > ActualBlock.end_column)
- {
- SWAP (ActualBlock.start_column, ActualBlock.end_column);
-
- ActualBlock.flags |= BF_COLUMNSWAP;
- }
- }
- } else if (ActualBlock.start_column > ActualBlock.end_column &&
- ( (ActualBlock.type == BT_VERTICAL) ||
- (ActualBlock.type == BT_NORMAL &&
- ActualBlock.start_line == ActualBlock.end_line)
- )
- )
- {
- SWAP (ActualBlock.start_column, ActualBlock.end_column);
-
- ActualBlock.flags |= BF_COLUMNSWAP;
- }
-
- /* D(bug("NEW: start:%3ld/%3ld end:%3ld/%3ld\n",
- ActualBlock.start_line+1,
- ActualBlock.start_column+1,
- ActualBlock.end_line+1,
- ActualBlock.end_column+1
- )); */
-
- D(bug("Flags %ld\n", ActualBlock.flags));
- } /* if (force) */
-
- draw: /* jump here is all DrawEvents are correctly initialized */
-
- /* Are we allowed to draw ? */
- if (!Nsu && !Ep->iconmode)
- {
- /* init rastport */
- rp = Ep->win->RPort;
-
- /* clip the update-region */
- new_rect.sl = Ep->topline;
- new_rect.el = new_rect.sl + Lines - 1;
- new_rect.sc = Ep->topcolumn;
- new_rect.ec = new_rect.sc + Columns - 1;
-
- /* make sure we don't get below the last line */
- if (new_rect.el >= Ep->lines)
- new_rect.el = Ep->lines - 1;
-
- /* clip away everything that exceeds the displayable area */
- and_rect_region (update, &new_rect);
- and_rect_region (old, &new_rect);
- and_rect_region (new, &new_rect);
-
- refresh_region (rp, update, 2);
- refresh_region (rp, old, 0);
- refresh_region (rp, new, 1);
-
- dispose_region (update);
- dispose_region (old);
- dispose_region (new);
- }
- } /* redraw_block */
-
-
- void refresh_region (RP * rp, struct RefreshRegion * region, int mode)
- {
- struct MyRegion * ptr;
- Line start_line, end_line;
- Column start_column, end_column;
- D(int t=0);
-
- for (ptr=GetHead(®ion->list); ptr; ptr=GetSucc(&ptr->node))
- {
- start_line = ptr->rect.sl;
- end_line = ptr->rect.el;
- start_column = ptr->rect.sc;
- end_column = ptr->rect.ec + 1;
-
- D(bug("Draw %ld: %ld (%2ld,%2ld) - (%2ld/%2ld)\n", t ++,
- mode, start_line+1, start_column+1, end_line+1, end_column+1));
-
- if (start_line > end_line ||
- start_column >= end_column)
- {
- D(bug("ERROR !!!!\n"));
- continue;
- }
-
- if (mode != 2)
- {
- if (mode == 1)
- SetAPen (rp, BLOCK_BPEN);
- else
- SetAPen (rp, TEXT_BPEN);
-
- SetWrMsk (rp, BLOCK_MASK);
- SetDrMd (rp, JAM2);
-
- RectFill (rp, COL(start_column - Ep->topcolumn),
- ROW(start_line - Ep->topline),
- COL(end_column - Ep->topcolumn)-1,
- ROW(end_line + 1 - Ep->topline)-1 );
- }
-
- for ( ; start_line <= end_line; start_line ++)
- redraw_textlineseg (start_line, start_column, end_column);
- }
- } /* refresh_region */
-
-
- /******************************************************************************
- ***** ENDE redraw.c
- ******************************************************************************/
-